package main

import (
	"fmt"
	"reflect"
	"sync"
)

//定义一个公共的范型接口
type GenergicMap interface {
	// 获取给定键值对应的元素值。若没有对应元素值则返回nil。
	Get(key interface{}) interface{}
	// 添加键值对，并返回与给定键值对应的旧的元素值。若没有旧元素值则返回(nil, true)。
	Put(key interface{}, elem interface{}) (interface{}, bool)
	// 删除与给定键值对应的键值对，并返回旧的元素值。若没有旧元素值则返回nil。
	Remove(key interface{}) interface{}
	// 清除所有的键值对。
	Clear()
	// 获取键值对的数量。
	Len() int
	// 判断是否包含给定的键值。
	Contains(key interface{}) bool
	// 获取已排序的键值所组成的切片值
	Keys() []interface{}
	// 获取已排序的元素值所组成的切片值。
	Elems() []interface{}
	// 获取已包含的键值对所组成的字典值。
	ToMap() map[interface{}]interface{}
	// 获取键的类型。
	KeyType() reflect.Type
	// 获取元素的类型。
	ElemType() reflect.Type
	// 判断key和value是否存在并且类型和map中的一致
	IsAcceptablePair(key, value interface{}) bool
}

// 有序的Map的接口类型。
type OrderedMap interface {
	GenergicMap // 泛化的Map接口
	// 获取第一个键值。若无任何键值对则返回nil。
	FirstKey() interface{}
	// 获取最后一个键值。若无任何键值对则返回nil。
	LastKey() interface{}
	// 获取由小于键值toKey的键值所对应的键值对组成的OrderedMap类型值。
	HeadMap(toKey interface{}) OrderedMap
	// 获取由小于键值toKey且大于等于键值fromKey的键值所对应的键值对组成的OrderedMap类型值。
	SubMap(fromKey interface{}, toKey interface{}) OrderedMap
	// 获取由大于等于键值fromKey的键值所对应的键值对组成的OrderedMap类型值。
	TailMap(fromKey interface{}) OrderedMap
}

//定义并发接口
type ConcurrencyMap interface {
	GenergicMap
}

//定义并发接口实现类
type ConcurrencyMapImpl struct {
	m        map[interface{}]interface{}
	keyType  reflect.Type //键的类型
	elemType reflect.Type //值的类型
	syncrw   sync.RWMutex //同步读写锁
}

//实现Put方法
func (this *ConcurrencyMapImpl) Put(key, value interface{}) (interface{}, bool) {
	//判断key,value是否合法
	if !this.IsAcceptablePair(key, value) {
		return nil, false
	}
	this.syncrw.Lock()
	defer this.syncrw.Unlock()
	oldElem := this.m[key]
	this.m[key] = value
	return oldElem, true
}

//通过key获取map中对应的值
func (this *ConcurrencyMapImpl) Get(key interface{}) interface{} {
	this.syncrw.RLock()         //加读锁
	defer this.syncrw.RUnlock() //释放读锁
	return this.m[key]
}

//移除map中的元素
func (this *ConcurrencyMapImpl) Remove(key interface{}) interface{} {
	oldElem := this.Get(key)
	//读锁释放之后再去加写锁
	this.syncrw.Lock()
	defer this.syncrw.Unlock()
	delete(this.m, key)
	return oldElem
}

//判断key,value都不空，并且key,value的类型和map中的类型一致
func (this *ConcurrencyMapImpl) IsAcceptablePair(key, value interface{}) bool {
	if key != nil && value != nil {
		return this.keyType == reflect.TypeOf(key) && this.elemType == reflect.TypeOf(value)
	}
	return false
}

//清空map
func (this *ConcurrencyMapImpl) Clear() {
	this.syncrw.Lock()
	defer this.syncrw.Unlock()
	for key := range this.m {
		this.Remove(key)
	}
}

//获取key和value的数量
func (this *ConcurrencyMapImpl) Len() int {
	i := 0
	for key := range this.m {
		fmt.Println(key)
		i++
	}
	return i
}

//map中是否存在制定的key
func (this *ConcurrencyMapImpl) Contains(key interface{}) bool {
	this.syncrw.RLock()
	defer this.syncrw.RUnlock()
	if _, ok := this.m[key]; ok {
		return true
	} else {
		return false
	}
}

//获取map中的所有keys
func (this *ConcurrencyMapImpl) Keys() []interface{} {
	this.syncrw.RLock()
	defer this.syncrw.RUnlock()
	var keys []interface{}
	for key := range this.m {
		keys = append(keys, key)
	}
	return keys
}

//获取map中的所有值
func (this *ConcurrencyMapImpl) Elems() []interface{} {
	this.syncrw.RLock()
	defer this.syncrw.RUnlock()
	var elems []interface{}
	for _, value := range this.m {
		elems = append(elems, value)
	}
	return elems
}

func (this *ConcurrencyMapImpl) ToMap() map[interface{}]interface{} {
	return this.m
}

func (this *ConcurrencyMapImpl) KeyType() reflect.Type {
	keys := this.Keys()
	if len(keys) == 0 {
		return nil
	} else {
		kType := reflect.TypeOf(keys[0])
		return kType
	}
}

func (this *ConcurrencyMapImpl) ElemType() reflect.Type {
	elems := this.Elems()
	if len(elems) == 0 {
		return nil
	} else {
		vType := reflect.TypeOf(elems[0])
		return vType
	}
}

func NewCurrencyMap(keyType, valueType reflect.Type) ConcurrencyMapImpl {
	return ConcurrencyMapImpl{
		m:        make(map[interface{}]interface{}),
		keyType:  keyType,
		elemType: valueType,
	}
}
